home *** CD-ROM | disk | FTP | other *** search
- # Grammar generation
- # for lisp lists with strings, ints, vars, print, and setq
-
- # set this variable to regenerate the grammar on each load
- REGENERATEONLOAD = 1
-
- import string
- GRAMMARSTRING ="""
- Value :: ## indicates Value is the root nonterminal for the grammar
- @R SetqRule :: Value >> ( setq var Value )
- @R ListRule :: Value >> ( ListTail
- @R TailFull :: ListTail >> Value ListTail
- @R TailEmpty :: ListTail >> )
- @R Varrule :: Value >> var
- @R Intrule :: Value >> int
- @R Strrule :: Value >> str
- @R PrintRule :: Value >> ( print Value )
- """
- COMPILEDFILENAME = "TESTLispG.py"
- MARSHALLEDFILENAME = "TESTLispG.mar"
- LISPCOMMENTREGEX = ";.*"
- INTREGEX = "["+string.digits+"]+"
- STRREGEX = '"[^\n"]*"'
- VARREGEX = "["+string.letters+"]["+string.letters+string.digits+"]*"
-
- ### declare interpretation functions and regex's for terminals
- def intInterp( str ):
- return string.atoi(str)
- def stripQuotes( str ):
- return str[1:len(str)-1]
- def echo(string):
- return string
- def DeclareTerminals(Grammar):
- Grammar.Addterm("int", INTREGEX, intInterp)
- Grammar.Addterm("str", STRREGEX, stripQuotes)
- Grammar.Addterm("var", VARREGEX, echo)
-
- ### declare the rule reduction interpretation functions.
- def EchoValue( list, Context ):
- return list[0]
- def VarValue( list, Context ):
- varName = list[0]
- if Context.has_key(varName):
- return Context[varName]
- else:
- raise NameError, "no such lisp variable in context "+varName
- def NilTail( list, Context ):
- return []
- def AddToList( list, Context ):
- return [ list[0] ] + list[1]
- def MakeList( list, Context ):
- return list[1]
- def DoSetq( list, Context):
- Context[ list[2] ] = list[3]
- return list[3]
- def DoPrint( list, Context ):
- print list[2]
- return list[2]
- def BindRules(Grammar):
- Grammar.Bind( "Intrule", EchoValue )
- Grammar.Bind( "Strrule", EchoValue )
- Grammar.Bind( "Varrule", VarValue )
- Grammar.Bind( "TailEmpty", NilTail )
- Grammar.Bind( "TailFull", AddToList )
- Grammar.Bind( "ListRule", MakeList )
- Grammar.Bind( "SetqRule", DoSetq )
- Grammar.Bind( "PrintRule", DoPrint )
-
- # This function generates the grammar and dumps it to a file.
- def GrammarBuild():
- import kjParseBuild
- LispG = kjParseBuild.NullCGrammar()
- LispG.SetCaseSensitivity(0) # grammar is not case sensitive for keywords
- DeclareTerminals(LispG)
- LispG.Keywords("setq print")
- LispG.punct("().")
- LispG.Nonterms("Value ListTail")
- LispG.comments([LISPCOMMENTREGEX])
- LispG.Declarerules(GRAMMARSTRING)
- LispG.Compile()
-
- print "dumping as python to "+COMPILEDFILENAME
- outfile = open(COMPILEDFILENAME, "w")
- LispG.Reconstruct("LispG",outfile,"GRAMMAR")
- outfile.close()
-
- print "dumping as binary to "+MARSHALLEDFILENAME
- outfile = open(MARSHALLEDFILENAME, "w")
- LispG.MarshalDump(outfile)
- outfile.close()
-
- BindRules(LispG)
- return LispG
-
- # this function initializes the compiled grammar from the generated file.
- def LoadLispG():
- import TESTLispG
- # reload to make sure we get the most recent version!
- # (only needed when debugging the grammar).
- reload(TESTLispG)
- LispG = TESTLispG.GRAMMAR()
- DeclareTerminals(LispG)
- BindRules(LispG)
- return LispG
-
- def unMarshalLispG():
- import kjParser
- infile = open(MARSHALLEDFILENAME, "r")
- LispG = kjParser.UnMarshalGram(infile)
- infile.close()
- DeclareTerminals(LispG)
- BindRules(LispG)
- return LispG
-
- ########## test the grammar generation
- if REGENERATEONLOAD:
- print "(re)generating the LispG grammar in file TESTLispG.py"
- Dummy = GrammarBuild()
- print "(re)generation done."
-
- print "loading grammar as python"
- LispG = LoadLispG()
- ### declare an initial context, and do some tests.
- Context = { 'x':3 }
- test1 = LispG.DoParse1( '()', Context)
- test2 = LispG.DoParse1( '(123)', Context)
- test3 = LispG.DoParse1( '(x)', Context)
- test4 = LispG.DoParse1( '" a string "', Context)
- test5 = LispG.DoParse1( '(setq y (1 2 3) )', Context )
- test6 = LispG.DoParse1( '(SeTq x ("a string" "another" 0))', Context )
- test7str = """
- ; this is a lisp comment
- (setq abc (("a" x)
- ("b" (setq d 12))
- ("c" y) ) ; another lisp comment
- )
- """
- test7 = LispG.DoParse1( test7str, Context)
- test8 = LispG.DoParse1( '(print (1 x d))', Context)
-
- print "unmarshalling the grammar"
- LispG2 = unMarshalLispG()
- ### declare an initial context, and do some tests.
- Context = { 'x':3 }
- test1 = LispG2.DoParse1( '()', Context)
- test2 = LispG2.DoParse1( '(123)', Context)
- test3 = LispG2.DoParse1( '(x)', Context)
- test4 = LispG2.DoParse1( '" a string "', Context)
- test5 = LispG2.DoParse1( '(setq y (1 2 3) )', Context )
- test6 = LispG2.DoParse1( '(SeTq x ("a string" "another" 0))', Context )
- test7str = """
- ; this is a lisp comment
- (setq abc (("a" x)
- ("b" (setq d 12))
- ("c" y) ) ; another lisp comment
- )
- """
- test7 = LispG2.DoParse1( test7str, Context)
- test8 = LispG2.DoParse1( '(print (1 x d))', Context)
-
-